-
Notifications
You must be signed in to change notification settings - Fork 0
mx-networkd: replace mxnetctl/mxvlanctl with a systemd-networkd generator #1
base: master
Are you sure you want to change the base?
Conversation
β¦tion
mxnetctl, mxvlanctl and the two oneshot units around them do three things
that systemd-networkd and udev can do themselves: rename interfaces by MAC
address, put the primary address and the default route on one of them, and
create the VLANs of the local host.
mx-networkd is a systemd generator that translates the existing
configuration files into .link, .netdev and .network files. Generators run
before any unit starts, including systemd-udevd, so the .link files are in
place before the first device is coldplugged. Everything is written to
/run/systemd/network/, which keeps /etc/systemd/network/ empty as required
and leaves /etc/local/mxnet, /etc/local/mxhost.conf and /etc/mxvlans as the
single source of truth, unchanged in format.
Three subcommands: `generate` (what the generator runs), `check` (parse and
report, for the master before pushing /etc/mxvlans) and `learn` (assign
netXX names to unknown MACs on a first boot, the one thing .link files
cannot do).
Notable details:
- systemd-networkd applies only the first matching .network file to an
interface, so all settings of one interface go into one file even when
they come from different input files.
- The output is deterministic, so re-running the generator on every
daemon-reload rewrites nothing.
- A broken line is skipped and logged rather than fatal: at boot a
partially configured network beats no network. `check` turns the same
problems into a non-zero exit status where a human can still fix them.
- The prefix length, gateway and broadcast address that were hard coded
in network.service are defaults now and can be overridden per host with
MX_PREFIXLEN, MX_GATEWAY and MX_BROADCAST.
No dependencies beyond the standard library. Nothing is enabled by this
commit; see mx-networkd/README.md for the per machine migration.
Written by OnkelClaude (Claude, KI-Bearbeitung im Auftrag von Boris) for
pmenzel/oc-exchange issue mariux64#3. `cargo test` passes (21 tests); the generator
has not yet run on a real MarIuX machine.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`make` builds the binary with cargo, `make install` puts it into /usr/sbin/mx-networkd and installs the same binary as the generator /usr/lib/systemd/system-generators/mx-networkd-generator (it recognises being called under that name). The install is skipped when the binary was not built, so `install.sh` keeps working standalone on a machine without a Rust toolchain. Installing the generator does not change any behaviour by itself: it only writes to /run/systemd/network/, which nothing reads unless systemd-networkd is enabled on that machine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
network.service removes the primary address in ExecStop, so 'systemctl disable --now network.service' over SSH drops the connection and locks the admin out of the machine. Flip the units without --now and let the reboot do the swap: the old units run until shutdown, the generator and the .link files take over at the next coldplug, and the two mechanisms never overlap. The rollback gets the same treatment. Addresses the review comment on PR #1. (Commit authored by OnkelClaude, KI-Bearbeitung im Auftrag von Boris.)
|
Tested on dose: |
|
\cc @donald |
| [package] | ||
| name = "mx-networkd" | ||
| version = "0.1.0" | ||
| edition = "2021" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you choose this name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π€ (Claude, im Auftrag von Boris)
The mx prefix follows the toolbox convention in this repository (mxnetctl, mxvlanctl, mxgrub, mxmount, mxraid, mxrouter, β¦): a MarIuX-specific tool that knows our configuration. -networkd because the program exists solely to feed systemd-networkd β it produces .link/.netdev/.network files and nothing else, so naming it after the thing it configures seemed clearest, mirroring how systemd-networkd itself is named. It is not a daemon; the "d" belongs to networkd, not to it.
I did consider mx-networkd-generator, but that felt redundant as a package name: the generator aspect is already expressed where systemd expects it, in the install name /usr/lib/systemd/system-generators/mx-networkd-generator (install.sh installs the same binary twice: as /usr/sbin/mx-networkd for check/learn/--dry-run use by admins, and under the -generator name for systemd). Something like mxnetgen would have been shorter but breaks the association with both systemd-networkd and the tag/unit names. Happy to rename if you prefer something else β it is one line in Cargo.toml plus the install.sh paths.
β bearbeitet mit Claude Fable 5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant just the line I commented on: edition = "2021". Why 2021?
|
Please write a helper script how to migrate systems. It might make sense to create a new tag mx-network-generator (no idea if hyphens are allowed in tags), and condition all the related services to it appropriately. |
β¦nerator Make the hostconfig tag mx-network-generator the single per-machine switch between the old and the new network setup (hyphens are fine in tag names: hostconfig matches tag terms with [a-z][a-z0-9$_-]*): * network.service and mxvlan.service get ConditionPathExists=!/node/tags/mx-network-generator, so they keep running everywhere until a machine carries the tag. * systemd-networkd.service gets a drop-in with ConditionPathExists=/node/tags/mx-network-generator, so it never fights the old units on a machine that has not been switched over. * mx-networkd generate writes nothing while the tag is absent and prunes files it wrote earlier, so a rollback needs nothing beyond removing the tag. /node/tags/ persists across boots and generators run before startup-tags.service, so the previous boot's populate-node result is what gates the generator. --dry-run ignores the tag so the preview always works; check now reports the tag state. Requested by Paul in PR #1 review. Written by OnkelClaude (AI) on behalf of Boris Bergenroth. Co-authored-by: OnkelClaude (AI) <borisbergenroth@googlemail.com>
Add mx-networkd/migrate-to-mx-networkd.sh, installed as /usr/sbin/migrate-to-mx-networkd. It prepares the reboot-based switchover without touching the running network, so it is safe over SSH and idempotent: * checks that binary, generator, drop-in and conditioned units are installed and that /etc/local/mxhost.conf and /etc/local/mxnet exist * validates the configuration with mx-networkd check and shows the generate --dry-run preview for comparison with the running state * verifies the mx-network-generator tag is set in /etc/hostconfig (and prints the exact line to add on the distmaster if not - /node/tags/ is rebuilt from /etc/hostconfig at every boot, so a locally touched tag file would not survive) * runs hostconfig --populate-node and enables systemd-networkd.service for the next boot only - nothing is started, stopped or reloaded * prints a summary and reboot-based rollback instructions Rewrite the README migration section around the tag and the script. Requested by Paul in PR #1 review. Written by OnkelClaude (AI) on behalf of Boris Bergenroth. Co-authored-by: OnkelClaude (AI) <borisbergenroth@googlemail.com>
|
π€ (Claude, im Auftrag von Boris) Implemented in 82d8245 and 264f72a on this branch. Tag: Conditioning (82d8245): the tag is now the single per-machine switch.
Migration helper (264f72a): One caveat worth knowing: since generators see the previous boot's One honest limitation: the Rust change (tag gate in β bearbeitet mit Claude Fable 5 |
β¦tion
mxnetctl, mxvlanctl and the two oneshot units around them do three things
that systemd-networkd and udev can do themselves: rename interfaces by MAC
address, put the primary address and the default route on one of them, and
create the VLANs of the local host.
mx-networkd is a systemd generator that translates the existing
configuration files into .link, .netdev and .network files. Generators run
before any unit starts, including systemd-udevd, so the .link files are in
place before the first device is coldplugged. Everything is written to
/run/systemd/network/, which keeps /etc/systemd/network/ empty as required
and leaves /etc/local/mxnet, /etc/local/mxhost.conf and /etc/mxvlans as the
single source of truth, unchanged in format.
Three subcommands: `generate` (what the generator runs), `check` (parse and
report, for the master before pushing /etc/mxvlans) and `learn` (assign
netXX names to unknown MACs on a first boot, the one thing .link files
cannot do).
Notable details:
- systemd-networkd applies only the first matching .network file to an
interface, so all settings of one interface go into one file even when
they come from different input files.
- The output is deterministic, so re-running the generator on every
daemon-reload rewrites nothing.
- A broken line is skipped and logged rather than fatal: at boot a
partially configured network beats no network. `check` turns the same
problems into a non-zero exit status where a human can still fix them.
- The prefix length, gateway and broadcast address that were hard coded
in network.service are defaults now and can be overridden per host with
MX_PREFIXLEN, MX_GATEWAY and MX_BROADCAST.
No dependencies beyond the standard library. Nothing is enabled by this
commit; see mx-networkd/README.md for the per machine migration.
`cargo test` passes (21 tests). Tested with follow-on patches on
*dose*, *sigusr2*, *fluffybutt*.
Assisted-by: Claude Fable 5 <noreply@anthropic.com> (thanks to @boris)
Resolves: #556
Link: pmenzel/oc-exchange#3
Link: pmenzel#1
π€ (Claude, im Auftrag von Boris)
Replaces
mxnetctl,mxvlanctl,network.serviceandmxvlan.servicewith a systemd generator that translates the existing configuration into systemd-networkd and udev files. For pmenzel/oc-exchange#3, written in Rust as requested.Nothing changes on any machine by merging this. The generator only writes to
/run/systemd/network/, which nothing reads unlesssystemd-networkdis enabled β and no machine has it enabled. The old units stay in place and keep working.The idea
Generators run at every boot and every
systemctl daemon-reload, before any unit starts β includingsystemd-udevd.service. So the.linkfiles exist before the first device is coldplugged, and/etc/systemd/network/stays permanently empty, which was the constraint in the issue. The three input files keep their current format and remain the single source of truth; nothing below/etcis written.What it produces
Run against the example data from the issue (
net00βnet03,MX_IPADDR=141.14.20.5, the fourtheinternetVLANs),mx-networkd generate --dry-rungives 13 files. The interesting one:That file is the reason this is a program and not two
sedscripts: systemd-networkd applies only the first matching.networkfile to an interface, so the address frommxhost.confand theVLAN=entries frommxvlanshave to end up in the same file. Splitting them across two files silently loses one of them.The rest is mechanical β one
.linkper MAC, one.netdevplus one.networkper VLAN, and a.networkfor a VLAN base device so networkd brings it up (whatip link set dev <base> updid).Three subcommands
generateβ what the generator runs. Output is deterministic (no time stamps), so re-running it on everydaemon-reloadrewrites nothing. It removes its own stale files and never touches files in/run/systemd/network/that it did not write.checkβ parse everything and exit non-zero on any problem, with file and line. Meant for the master before/etc/mxvlansis pushed, so a typo stops there instead of on 300 machines:learnβ the one thing.linkfiles cannot do: give a never-seen MAC a name. Same algorithm as mxnetctl (prefernetNNmatching the kernel'sethN, else lowest free), same refusal to write when/etc/local/USB.usbexists. It does not rename anything; udev does that after the nextgenerate.Deliberate choices
checkmakes the same problem fatal where a human can still fix it.network.service(prefix length 20, gateway 141.14.16.128, broadcast) are defaults now, overridable per host withMX_PREFIXLEN,MX_GATEWAY,MX_BROADCAST. Behaviour is unchanged when they are absent.applysubcommand. Applying isnetworkctl reload. A second implementation of "make the kernel match the files" is exactly the divergence this is meant to remove.stdonly, no build script. It runs before most of the system exists and everyone maintaining the network configuration should be able to read all of it.Testing
cargo testβ 21 tests covering the parsers (including the malformed cases), the file layout, determinism, thesync/prune logic andlearnagainst a fake/sys. Plus a manual--dry-runagainst the example data above.Not tested on a real machine. It has never run on a MarIuX host, and I cannot do that from here. Before anything is switched over, please run
mx-networkd checkandmx-networkd generate --dry-runon a few different hosts (a desktop, a server with VLANs, one with several NICs) and compare againstip -br addrandip -d link show type vlan. The migration steps, including how to go back, are inmx-networkd/README.md.Known gaps
learnassumesethNkernel names, i.e.net.ifnames=0β the same assumption mxnetctl made./etc/local/mxnetneeds a reboot. Unchanged from today.β bearbeitet mit Claude Fable 5